/*******************************************************************************
*  file    : uzdatagetter.cpp
*  created : 05.06.2013
*  author  : Slyshyk Oleksiy (alexSlyshyk@gmail.com)
*******************************************************************************/

#include "uzdatagetter.hpp"

#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>

#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonParseError>

#include <QDataStream>
#include <QDebug>

#include <qlogger.hpp>

namespace {
QLogger* l = QLoggerEngine::getLogger("core");
}

UzDataGetter::UzDataGetter(QObject *parent) :
    QObject(parent)
{
    m_accessManager = new QNetworkAccessManager(this);
}

QVector<CityData> UzDataGetter::cities(const QString& key) const
{
    if( m_cities.keys().contains(key) )
        return m_cities[key];

    return QVector<CityData>();
}

QVector<TrainData> UzDataGetter::trainData(int key) const
{
    if ( m_trainData.keys().contains(key) )
        return m_trainData[key];

    return QVector<TrainData>();
}

void UzDataGetter::requestCities(const QString& nm)
{
    if(nm.size() < 2)
        {
            logError(l)<<QString(tr("City name less than 2 char."));
            return;
        }
    QUrl url = QUrl(QString("http://booking.uz.gov.ua/ru/purchase/station/%1").arg(nm.left(2)));
    logDebug(l)<<"Load Url : "<<url.toString();

    QNetworkRequest request(url);
    request.setRawHeader("Host", "booking.uz.gov.ua");
    request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:20.0) Gecko/20100101 Firefox/20.0");
    request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    request.setRawHeader("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3");
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
    request.setRawHeader("Referer", "http://booking.uz.gov.ua/ru/");
    request.setRawHeader("Connection", "keep-alive");
    request.setRawHeader("Pragma", "no-cache");
    request.setRawHeader("Content-Length", "0");

    QNetworkReply* reply = m_accessManager->get(request);
    connect(reply, SIGNAL(finished()), this, SLOT(replyCities()) );
}

void UzDataGetter::replyCities()
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(const_cast<QObject*>(sender()));
    QByteArray reply_data = reply->readAll();
    reply->deleteLater();

    QJsonParseError jpe;
    QJsonDocument jd = QJsonDocument::fromJson(reply_data, &jpe);

    if( jpe.error !=  QJsonParseError::NoError)
        {
            logError(l)<<jpe.errorString();
            return;
        }

    QVector<CityData> res;
    QJsonValue jsv = jd.object().value("value");
    if(jsv.isArray())
        {
            foreach (const QJsonValue& j, jsv.toArray())
                {
                    CityData cd;
                    cd.name = j.toObject().value("title").toString();
                    cd.id   = QString::number(static_cast<int>(j.toObject().value("station_id").toDouble()));
                    res.append(cd);
                    //logDebug(l)<<cd.name<<":\t"<<cd.id;
                }
        }
    if( res.size() )
        {
            m_cities[res.at(0).name.left(2).toUpper()] = res;
            logDebug(l)<<"emit cityes with key:"<<res[0].name;
            emit citiesLoaded(res.at(0).name.left(2).toUpper());
        }
}

void UzDataGetter::requestTicketInfo(TicketInfo ti)
{
    QUrl url = QUrl(tr("http://booking.uz.gov.ua/ru/purchase/search/"));
    logDebug(l)<<"Url : "<<url.toString();

    QNetworkRequest request(url);
    request.setRawHeader("Host", "booking.uz.gov.ua");
    request.setRawHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:20.0) Gecko/20100101 Firefox/20.0");
    request.setRawHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    request.setRawHeader("Accept-Language", "ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3");
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
    request.setRawHeader("Referer", "http://booking.uz.gov.ua/ru/");
    request.setRawHeader("Connection", "keep-alive");
    request.setRawHeader("Pragma", "no-cache");
    request.setRawHeader("GV-Ajax", "1");
    request.setRawHeader("GV-Referer", "http://booking.uz.gov.ua/ru/");
    request.setRawHeader("GV-Screen", "1280x800");
    request.setRawHeader("GV-Unique-Host", "1");

    QByteArray data;
    data += "date_dep="       +ti.date                    +"&";
    data += "station_from="   +ti.from.toPercentEncoding()+"&";
    data += "station_id_from="+ti.from_id                 +"&";
    data += "station_till="   +ti.to.toPercentEncoding()  +"&";
    data += "station_id_till="+ti.to_id                   +"&";
    data += "time_dep=00:00&";
    data += "search=";

    request.setRawHeader("Content-Length",QByteArray::number(data.size()));

    QNetworkReply* reply = m_accessManager->post(request,data);
    reply->setProperty("ti_id",QVariant(ti.id));
    connect(reply, SIGNAL(finished()), this, SLOT(replyTicketInfo()));
}

void UzDataGetter::replyTicketInfo()
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(const_cast<QObject*>(sender()));

    if(reply->error() != QNetworkReply::NoError)
        {
            logError(l)<<"Request Error. "<<reply->errorString();
        }
    QByteArray reply_data = reply->readAll();
    int ti_id = reply->property("ti_id").toInt();

    reply->deleteLater();

    QJsonParseError jpe;
    QJsonDocument jd = QJsonDocument::fromJson(reply_data, &jpe);
    if( jpe.error !=  QJsonParseError::NoError)
        {
            logError(l)<<jpe.errorString();
            return;
        }
    QJsonValue jse = jd.object().value("error");
    if( jse.toBool() )
        {
            logError(l)<<jd.object().value("value").toString();
            return;
        }
    QJsonValue jsv = jd.object().value("value");
    if(jsv.isArray())
        {
            QVector<TrainData> trd;
            foreach (const QJsonValue& j, jsv.toArray())
                {
                    TrainData td;
                    td.num   = j.toObject().value("num").toString();
                    td.model = static_cast<int>(j.toObject().value("model").toDouble());
                    td.from = StationPoint(j.toObject().value("from").toObject());
                    td.till = StationPoint(j.toObject().value("till").toObject());

                    foreach (const QJsonValue& jv, j.toObject().value("types").toArray())
                        {
                            td.places.push_back( PlaceType(jv.toObject()) );
                        }
                    trd.push_back(td);

                    qDebug()<<"Traindata:"<<td.num<<"  "<<td.model;
                    qDebug()<<"From:"<<td.from.station_id<<"  "<<td.from.station_name
                           << "  " << td.from.time;
                    qDebug()<<"Places:"<<td.places[0].letter<<" "<<td.places[0].title
                           <<" "<<td.places[0].places;
                }
            m_trainData[ti_id] = trd;
            emit trainDataReady(ti_id);
        }
}

void UzDataGetter::requestCoaches()
{
    QUrl url = QUrl(tr("http://booking.uz.gov.ua/ru/purchase/coaches/"));
    QNetworkRequest request(url);
}

void UzDataGetter::replyCoaches()
{

}

